跳到主要内容

Linux 的命名空间

Linux 的命名空间是什么?

Linux 的命名空间(Namespace)是 Linux 内核提供的一种隔离机制,用于将全局资源分割成若干个局部空间,使得每个空间内的进程只能看到自己所在的空间内的资源,从而实现对各种系统资源(如进程、网络、文件系统等)的隔离。

命名空间可以分为以下几种类型:

  • 进程命名空间(PID Namespace):用于隔离进程 ID,每个进程都在自己的进程命名空间内运行,其它进程无法看到该进程的存在。
  • 网络命名空间(Net Namespace):用于隔离网络设备、网络栈、端口等,每个网络命名空间内都有自己的网络栈、IP 地址、端口,不同命名空间之间的网络资源相互独立。
  • 挂载命名空间(Mount Namespace):用于隔离文件系统挂载点,每个挂载命名空间内有自己的根文件系统、挂载点等,不同命名空间之间的文件系统相互独立。
  • IPC 命名空间(IPC Namespace):用于隔离 Inter-Process Communication,如消息队列、信号量和共享内存等,不同命名空间之间的 IPC 资源相互独立。
  • UTS 命名空间(UTS Namespace):用于隔离节点名和域名等系统标识符,每个 UTS 命名空间内都有自己的主机名和 NIS 域名,不同命名空间之间的系统标识符相互独立。
  • 用户命名空间(User Namespace):用于隔离用户和用户组标识符,允许在不同命名空间内使用相同标识符,从而避免权限问题。

namespace 的本质就是把原来所有进程全局共享的资源拆分成了很多个一组一组进程共享的资源,当一个 namespace 里面的所有进程都退出时,namespace 也会被销毁,所以抛开进程谈 namespace 没有意义

检查进程的命名空间

如下检查进程的命名空间

# $$ 这个程式的PID(脚本运行的当前进程ID号)
$ ls -l /proc/$$/ns
lrwxrwxrwx 1 alsritter alsritter 0 Apr 14 16:25 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 alsritter alsritter 0 Apr 14 16:25 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 alsritter alsritter 0 Apr 14 16:25 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 alsritter alsritter 0 Apr 14 16:25 net -> 'net:[4026532008]'
lrwxrwxrwx 1 alsritter alsritter 0 Apr 14 16:25 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 alsritter alsritter 0 Apr 14 16:25 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 alsritter alsritter 0 Apr 14 16:25 time -> 'time:[4026531834]'
lrwxrwxrwx 1 alsritter alsritter 0 Apr 14 16:25 time_for_children -> 'time:[4026531834]'
lrwxrwxrwx 1 alsritter alsritter 0 Apr 14 16:25 user -> 'user:[4026531837]'
lrwxrwxrwx 1 alsritter alsritter 0 Apr 14 16:25 uts -> 'uts:[4026531838]'

命名空间有什么具体的用途呢?

命名空间是Linux中提供的一种隔离机制,主要用于实现资源的隔离,避免不同进程之间产生互相干扰的情况,从而保证系统的高效性和安全性。具体来说,命名空间的用途如下:

1、进行系统资源的隔离。命名空间可以针对不同的资源进行隔离,如进程、网络、文件系统等,从而避免进程之间的资源共享和冲突,保证系统的安全性和可靠性。

2、实现容器技术。容器是一种轻量级的虚拟化技术,可以快速创建和删除应用程序运行环境,并提供了一种标准化的方式来管理和部署应用程序。容器技术主要依赖于命名空间进行资源的隔离,从而实现不同容器之间的互相独立。

3、进行进程的隔离和管理。命名空间可以实现进程的隔离和管理,使得每个进程都可以看到自己所在的命名空间内的进程,而看不到其它命名空间中的进程,从而保证了进程之间的隔离和安全性。

4、实现进程及子进程的资源控制。通过对进程的命名空间进行设置,可以限制进程及其子进程对资源的使用,从而实现资源的控制和管理,避免进程分配过多的资源导致系统崩溃等问题。

5、实现平台的轻量级定制。命名空间可以让系统管理员对操作系统的不同部分进行划分,从而实现不同的功能和特性,使得系统具有更高的灵活性和可定制性。例如,可以将内核层与用户层分离,或者将操作系统和应用程序分离等等。

怎么样创建一个命名空间

unshare 命令

使用 unshare 命令,unshare 命令可以创建并进入一个新命名空间。例如,创建并进入一个新的网络命名空间:

sudo unshare --net /bin/bash

上面的命令将进入一个新的命名空间,并启动一个新的 Bash shell,在该命名空间中,网络资源将被隔离。其中,--net 选项表示隔离网络命名空间。

使用 ip netns 命令

ip 命令是 Linux 中管理网络的命令行工具,可以用来创建和管理网络命名空间。例如,创建一个名为 ns1 的网络命名空间:

sudo ip netns add ns1

上面的命令创建了一个名为 ns1 的网络命名空间。可以使用 ip netns list 命令查看系统当前的网络命名空间列表。

使用 docker run 命令

Docker 是一种常用的容器技术,可以使用 docker run 命令来创建和管理容器,其中命名空间是一种常见的隔离方式。例如,创建一个名为 mycontainer 的容器,并进入该容器的 Bash shell:

docker run -it --name mycontainer --rm ubuntu /bin/bash

上面的命令将创建一个 Ubuntu 容器,并进入该容器的 Bash shell,在该容器中,进程、网络、文件系统等资源都将被隔离到命名空间中,不受主机上其他进程的影响。其中,--name 选项表示容器的名字,--rm 选项表示容器退出后自动删除,/bin/bash 表示在容器中启动 Bash shell。

Linux 的命名空间类型

目前,Linux 内核里面实现了7种不同类型的 namespace。

名称        宏定义             隔离内容
Cgroup CLONE_NEWCGROUP Cgroup root directory (since Linux 4.6)
IPC CLONE_NEWIPC System V IPC, POSIX message queues (since Linux 2.6.19)
Network CLONE_NEWNET Network devices, stacks, ports, etc. (since Linux 2.6.24)
Mount CLONE_NEWNS Mount points (since Linux 2.4.19)
PID CLONE_NEWPID Process IDs (since Linux 2.6.24)
User CLONE_NEWUSER User and group IDs (started in Linux 2.6.23 and completed in Linux 3.8)
UTS CLONE_NEWUTS Hostname and NIS domain name (since Linux 2.6.19)

下面简要介绍一个以上不同类型的命名空间的作用:

IPC 命名空间

用于隔离进程间通讯所需的资源( System V IPC, POSIX message queues),PID 命名空间和 IPC 命名空间可以组合起来用,同一个 IPC 名字空间内的进程可以彼此看见,允许进行交互,不同空间进程无法交互

网络命名空间

Network Namespace 为进程提供了一个完全独立的网络协议栈的视图。包括网络设备接口,IPv4 和 IPv6 协议栈,IP 路由表,防火墙规则,sockets 等等。一个 Network Namespace 提供了一份独立的网络环境,就跟一个独立的系统一样。

挂载命名空间

每个进程都存在于一个 mount Namespace 里面,mount Namespace 为进程提供了一个文件层次视图。如果不设定这个 flag,子进程和父进程将共享一个 mount Namespace,其后子进程调用 mount 或 umount 将会影响到所有该 Namespace 内的进程。如果子进程在一个独立的 mount Namespace 里面,就可以调用 mount 或 umount 建立一份新的文件层次视图。

进程命名空间

PID Namespace,用于隔离进程 ID,每个进程都在自己的进程命名空间内运行,其它进程无法看到该进程的存在

同一个进程,在不同的命名空间进程号不同,进程命名空间是一个父子结构,子空间对于父空间可见。

用户命名空间

User Namespace:用于隔离用户和用户组标识符,允许在不同命名空间内使用相同标识符,从而避免权限问题。

UTS 命名空间

User Namespace 决定了运行在命名空间里的进程能看见哪些主机名和域名。

通过分派两个不同的 UTS 命名空间给一对进程, 能使它们看见不同的本地主机名。 换句话说,这两个进程就好像正在两个不同的机器上运行一样(至少就主机名而言是这样的)。